package com.canaan.business.schedule;

import com.canaan.business.common.enums.agv.AgvEnum;
import com.canaan.business.common.enums.storehouse.StoreHouseLocationTypeEnum;
import com.canaan.business.common.enums.storehouse.StorehouseStockStatusEnum;
import com.canaan.business.common.helper.EmptyStockHelper;
import com.canaan.business.domain.basic.WmsStorehouseLocation;
import com.canaan.business.domain.inOutStock.OutStockBill;
import com.canaan.business.domain.inOutStock.OutStockBillDetail;
import com.canaan.business.domain.inOutStock.SplitBill;
import com.canaan.business.domain.storehouse.WmsStorehouseStock;
import com.canaan.business.domain.vo.WmsStorehouseStockVo;
import com.canaan.business.service.agv.IAgvTaskDispatchService;
import com.canaan.business.service.basic.IWmsStorehouseLocationService;
import com.canaan.business.service.inOutStock.IAdjustLocationBillService;
import com.canaan.business.service.inOutStock.IOutStockBillService;
import com.canaan.business.service.inOutStock.ISplitBillService;
import com.canaan.business.service.storehouse.IWmsStorehouseStockService;
import com.canaan.common.utils.StringUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component("AutoOutStockSchedule")
public class AutoOutStockSchedule {

    @Resource
    private IOutStockBillService outStockBillService;
    @Resource
    private IWmsStorehouseStockService storehouseStockService;
    @Resource
    private IWmsStorehouseLocationService locationService;
    @Resource
    private IAgvTaskDispatchService agvTaskDispatchService;
    @Resource
    private ISplitBillService splitBillService;
    @Resource
    IAdjustLocationBillService adjustLocationBillService;
    @Resource
    private EmptyStockHelper emptyStockHelper;
    /**
     * 申请空料架
     */
    @ApiOperation(value = "无终点的出库单申请库位", notes = "无终点的出库单申请库位")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void apply() {
        List<OutStockBill> outStockBillList=outStockBillService.selectEmptyDestOutStockBill();
        if(outStockBillList==null||outStockBillList.size()==0){
            return;
        }
        OutStockBill outStockBill=null;
        WmsStorehouseStockVo stockVo=null;
        for(OutStockBill item : outStockBillList){
            if(StringUtils.isEmpty(item.getSourceLocation())){
                continue;
            }
            if(StringUtils.isEmpty(item.getTrayNo())){
                continue;
            }
            WmsStorehouseStock sourceStock=storehouseStockService.selectWmsStorehouseStockByTrayNo(item.getTrayNo());
            if(sourceStock==null){
                continue;
            }
            if(item.getTrayNo().equals(sourceStock.getTrayNo())){
                outStockBill=item;

                List<WmsStorehouseStockVo> outStockVos=storehouseStockService.selectEmpWmsStorehouseOutStockList();
                if(outStockVos==null||outStockVos.size()==0){
                    continue;
                }

                stockVo= getStorehouseStock(outStockBill,outStockVos);
                if(stockVo==null){
                    continue;
                }
                break;
            }
        }
        if(outStockBill!=null&&stockVo!=null){
            handleOutStockBill(outStockBill,stockVo);
        }
    }

    /**
     * 处理出库单
     */
    private void handleOutStockBill(OutStockBill outStockBill,WmsStorehouseStockVo stockVo){
        outStockBill.setDestLocation(stockVo.getStorehouseLocationNo());
        outStockBillService.updateOutStockBill(outStockBill);
        //锁定源库位
        WmsStorehouseStock sourceStock=storehouseStockService.selectWmsStorehouseStockByLocationNo(outStockBill.getSourceLocation());
        if(sourceStock==null){
            throw new RuntimeException("源库位"+outStockBill.getSourceLocation()+"不存在库存数据");
        }
        WmsStorehouseLocation sourceLocation=locationService.selectWmsStorehouseLocationByNo(outStockBill.getSourceLocation());
        if(sourceLocation==null){
            throw new RuntimeException("源库位"+sourceStock.getStorehouseLocationNo()+"不存在");
        }
        //锁定目标库位
        WmsStorehouseStock destStock=storehouseStockService.selectWmsStorehouseStockByLocationNo(outStockBill.getDestLocation());
        if(destStock==null){
            throw new RuntimeException("库位"+outStockBill.getDestLocation()+"不存在库存数据");
        }
        destStock.setStatus(StorehouseStockStatusEnum.LOCK.getCode());
        storehouseStockService.updateWmsStorehouseStock(destStock);
        WmsStorehouseLocation destLocation=locationService.selectWmsStorehouseLocationByNo(destStock.getStorehouseLocationNo());
        if(destLocation==null){
            throw new RuntimeException("源库位"+destStock.getStorehouseLocationNo()+"不存在");
        }
        //创建AGV任务
        agvTaskDispatchService.createTaskDispatch(outStockBill.getNo(),sourceLocation,destLocation, AgvEnum.TASK_TYPE.OUT,
                sourceStock.getContainerNo(),sourceStock.getTrayNo());
        SplitBill splitBillQuery=new SplitBill();
        splitBillQuery.setRelOrderNo(outStockBill.getNo());
        splitBillQuery.setDelFlag("0");
        //分拣单设置库位
        List<SplitBill> splitBills=splitBillService.selectSplitBillList(splitBillQuery);
        if(splitBills.size() != 0){
            SplitBill splitBill=splitBills.get(0);
            splitBill.setLocation(stockVo.getStorehouseLocationNo());
            splitBillService.updateSplitBill(splitBill);
        }
        //分析是否调库单
        emptyStockHelper.generateAdjustLocation(stockVo.getStorehouseLocationNo(),
                stockVo.getIsInner(),stockVo.getInnerLocation(),outStockBill.getNo());
    }

    /**
     * 获取相同出库库位
     * @param outStockBill 出库单
     * @param stockVos 出库库位集合
     * @return 出库库位
     */
    private WmsStorehouseStockVo getStorehouseStock(OutStockBill outStockBill,List<WmsStorehouseStockVo> stockVos){
        for(WmsStorehouseStockVo vo:stockVos){
            if(StoreHouseLocationTypeEnum.OUT_SORTING_STATION.getCode().equals(vo.getLocationType())&&
                    "1".equals(outStockBill.getIsSplit())){
                return vo;
            }
            else if(StoreHouseLocationTypeEnum.OUT_DOCKING_STATION.getCode().equals(vo.getLocationType())&&
                    "0".equals(outStockBill.getIsSplit())){
                return vo;
            }
        }
        return null;
    }


}
